﻿jQuery.fn.calendarioDW = function() {
    this.each(function() {
        //saber si estoy mostrando el calendario
        var mostrando = false;
        //variable con el calendario
        var calendario;
        //variable con los días del mes
        var capaDiasMes;
        //variable para mostrar el mes y ano que se está viendo
        var capaTextoMesAnoActual = $('<div class="visualmesano"></div>');
        //iniciales de los días de la semana
        var dias = ["l", "m", "x", "j", "v", "s", "d"];
        //nombres de los meses
        var nombresMes = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]

        //elemento input
        var elem = $(this);
        //creo un enlace-botón para activar el calendario
        var boton = $("<a class='botoncal' href='#'><span></span></a>");
        //inserto el enlace-botón después del campo input
        elem.after(boton);

        //evento para clic en el botón
        boton.click(function(e) {
            e.preventDefault();
            mostrarCalendario();
        });
        //evento para clic en el campo
        elem.click(function(e) {
            this.blur();
            mostrarCalendario();
        });

        //función para mostrar el calendario
        function mostrarCalendario() {
            if (!mostrando) {
                mostrando = true;
                //es que hay que mostrar el calendario
                //dias de la semana
                var capaDiasSemana = $('<div class="diassemana"></div>');
                $(dias).each(function(indice, valor) {
                    var codigoInsertar = '<span';
                    if (indice == 0) {
                        codigoInsertar += ' class="primero"';
                    }
                    if (indice == 6) {
                        codigoInsertar += ' class="domingo ultimo"';
                    }
                    codigoInsertar += ">" + valor + '</span>';

                    capaDiasSemana.append(codigoInsertar);
                });

                //capa con los días del mes
                capaDiasMes = $('<div class="diasmes"></div>');

                //un objeto de la clase date para calculo de fechas
                var objFecha = new Date();
                //miro si en el campo INPUT tengo alguna fecha escrita
                var textoFechaEscrita = elem.val();
                if (textoFechaEscrita != "") {
                    if (validarFechaEscrita(textoFechaEscrita)) {
                        var arrayFechaEscrita = textoFechaEscrita.split("/");
                        //hago comprobación sobre si el año tiene dos cifras
                        if (arrayFechaEscrita[2].length == 2) {
                            if (arrayFechaEscrita[2].charAt(0) == "0") {
                                arrayFechaEscrita[2] = arrayFechaEscrita[2].substring(1);
                            }
                            arrayFechaEscrita[2] = parseInt(arrayFechaEscrita[2]);
                            if (arrayFechaEscrita[2] < 50)
                                arrayFechaEscrita[2] += 2000;
                        }
                        objFecha = new Date(arrayFechaEscrita[2], arrayFechaEscrita[1] - 1, arrayFechaEscrita[0])
                    }
                }

                //mes y año actuales
                var mes = objFecha.getMonth();
                var ano = objFecha.getFullYear();
                //muestro los días del mes y año dados
                muestraDiasMes(mes, ano);

                //control para ocultar el calendario
                var botonCerrar = $('<a href="#" class="calencerrar"><span></span></a>');
                botonCerrar.click(function(e) {
                    e.preventDefault();
                    calendario.hide("slow");
                })
                var capaCerrar = $('<div class="capacerrar"></div>');
                capaCerrar.append(botonCerrar)

                //controles para ir al mes siguiente / anterior
                var botonMesSiguiente = $('<a href="#" class="botonmessiguiente"><span></span></a>');
                botonMesSiguiente.click(function(e) {
                    e.preventDefault();
                    mes = (mes + 1) % 12;
                    if (mes == 0)
                        ano++;
                    capaDiasMes.empty();
                    muestraDiasMes(mes, ano);
                })
                var botonMesAnterior = $('<a href="#" class="botonmesanterior"><span></span></a>');
                botonMesAnterior.click(function(e) {
                    e.preventDefault();
                    mes = (mes - 1);
                    if (mes == -1) {
                        ano--;
                        mes = 11
                    }
                    capaDiasMes.empty();
                    muestraDiasMes(mes, ano);
                })
                var botonCambioAno = $('<a href="#" class="botoncambiaano"><span></span></a>')
                botonCambioAno.click(function(e) {
                    e.preventDefault();
                    var botonActivoSelAnos = $(this);
                    //creo una capa con una serie de años para elegir
                    var capaAnos = $('<div class="capaselanos"></div>');
                    //genero 10 años antes y 10 después
                    for (var i = ano - 10; i <= ano + 10; i++) {
                        var codigoEnlace = '<a href="#"';
                        if (i == ano)
                            codigoEnlace += ' class="seleccionado"';
                        if (i == ano + 10)
                            codigoEnlace += ' class="ultimo"';
                        codigoEnlace += '><span>' + i + '</span></a>';
                        var opcionAno = $(codigoEnlace);
                        opcionAno.click(function(e) {
                            e.preventDefault();
                            ano = parseInt($(this).children().text());
                            capaDiasMes.empty();
                            muestraDiasMes(mes, ano);
                            capaAnos.slideUp();
                            capaAnos.detach();
                        })
                        capaAnos.append(opcionAno);
                    }
                    //coloco la capa en la página
                    $(document.body).append(capaAnos);
                    //posiciono la capa
                    capaAnos.css({
                        top: (botonActivoSelAnos.offset().top + 12) + "px",
                        left: (botonActivoSelAnos.offset().left - 25) + "px"
                    })
                    capaAnos.slideDown();
                })

                //capa para mostrar el texto del mes y ano actual
                var capaTextoMesAno = $('<div class="textomesano"></div>');
                var capaTextoMesAnoControl = $('<div class="mesyano"></div>')
                capaTextoMesAno.append(botonMesSiguiente);
                capaTextoMesAno.append(botonMesAnterior);
                capaTextoMesAno.append(capaTextoMesAnoControl);
                capaTextoMesAnoControl.append(capaTextoMesAnoActual);
                capaTextoMesAnoControl.append(botonCambioAno);

                //calendario y el borde
                calendario = $('<div class="capacalendario"></div>');
                var calendarioBorde = $('<div class="capacalendarioborde"></div>');
                calendario.append(calendarioBorde);
                calendarioBorde.append(capaCerrar);
                calendarioBorde.append(capaTextoMesAno);
                calendarioBorde.append(capaDiasSemana);
                calendarioBorde.append(capaDiasMes);

                //inserto el calendario en el documento
                $(document.body).append(calendario);
                //lo posiciono con respecto al boton
                calendario.css({
                    top: boton.offset().top + "px",
                    left: (boton.offset().left + 20) + "px"
                })
                //muestro el calendario
                calendario.show("slow");

            } else {
                //es que el calendario ya se estaba mostrando...
                calendario.fadeOut("fast");
                calendario.fadeIn("fast");

            }

        }

        function muestraDiasMes(mes, ano) {
            //console.log("muestro (mes, ano): ", mes, " ", ano)
            //muestro en la capaTextoMesAno el mes y ano que voy a dibujar
            capaTextoMesAnoActual.text(nombresMes[mes] + " " + ano);

            //muestro los días del mes
            var contadorDias = 1;

            //calculo la fecha del primer día de este mes
            var primerDia = calculaNumeroDiaSemana(1, mes, ano);
            //calculo el último día del mes
            var ultimoDiaMes = ultimoDia(mes, ano);

            //escribo la primera fila de la semana
            for (var i = 0; i < 7; i++) {
                if (i < primerDia) {
                    //si el dia de la semana i es menor que el numero del primer dia de la semana no pongo nada en la celda
                    var codigoDia = '<span class="diainvalido';
                    if (i == 0)
                        codigoDia += " primero";
                    codigoDia += '"></span>';
                } else {
                    var codigoDia = '<span';
                    if (i == 0)
                        codigoDia += ' class="primero"';
                    if (i == 6)
                        codigoDia += ' class="ultimo domingo"';
                    codigoDia += '>' + contadorDias + '</span>';
                    contadorDias++;
                }
                var diaActual = $(codigoDia);
                capaDiasMes.append(diaActual);
            }

            //recorro todos los demás días hasta el final del mes
            var diaActualSemana = 1;
            while (contadorDias <= ultimoDiaMes) {
                var codigoDia = '<span';
                //si estamos a principio de la semana escribo la clase primero
                if (diaActualSemana % 7 == 1)
                    codigoDia += ' class="primero"';
                //si estamos al final de la semana es domingo y ultimo dia
                if (diaActualSemana % 7 == 0)
                    codigoDia += ' class="domingo ultimo"';
                codigoDia += '>' + contadorDias + '</span>';
                contadorDias++;
                diaActualSemana++;
                var diaActual = $(codigoDia);
                capaDiasMes.append(diaActual);
            }

            //compruebo que celdas me faltan por escribir vacias de la última semana del mes
            diaActualSemana--;
            if (diaActualSemana % 7 != 0) {
                //console.log("dia actual semana ", diaActualSemana, " -- %7=", diaActualSemana%7)
                for (var i = (diaActualSemana % 7) + 1; i <= 7; i++) {
                    var codigoDia = '<span class="diainvalido';
                    if (i == 7)
                        codigoDia += ' ultimo'
                    codigoDia += '"></span>';
                    var diaActual = $(codigoDia);
                    capaDiasMes.append(diaActual);
                }
            }

            //crear el evento para cuando se pulsa un día de mes
            //console.log(capaDiasMes.children());
            capaDiasMes.children().click(function(e) {
                var numDiaPulsado = $(this).text();
                if (numDiaPulsado != "") {
                    elem.val(numDiaPulsado + "/" + (mes + 1) + "/" + ano);
                    calendario.fadeOut();
                }
            })
        }
        //función para calcular el número de un día de la semana
        function calculaNumeroDiaSemana(dia, mes, ano) {
            var objFecha = new Date(ano, mes, dia);
            var numDia = objFecha.getDay();
            if (numDia == 0)
                numDia = 6;
            else
                numDia--;
            return numDia;
        }

        //función para ver si una fecha es correcta
        function checkdate(m, d, y) {
            // función por http://kevin.vanzonneveld.net
            // extraida de las librerías phpjs.org manual en http://www.desarrolloweb.com/manuales/manual-librerias-phpjs.html
            return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
        }

        //funcion que devuelve el último día de un mes y año dados
        function ultimoDia(mes, ano) {
            var ultimo_dia = 28;
            while (checkdate(mes + 1, ultimo_dia + 1, ano)) {
                ultimo_dia++;
            }
            return ultimo_dia;
        }

        function validarFechaEscrita(fecha) {
            var arrayFecha = fecha.split("/");
            if (arrayFecha.length != 3)
                return false;
            return checkdate(arrayFecha[1], arrayFecha[0], arrayFecha[2]);
        }
    });
    return this;
};